﻿using System;
using System.Reflection;
using System.Globalization;
using Optparse;

namespace Optparse.Tester.Proxy {
    public class TinyCharBufferProxy {
        private object proxyObject;
        private Type proxyobjectType;

        public TinyCharBufferProxy(int capacity) {
            Type optParser = typeof(OptionParser);
            Type cmdParser = optParser.GetNestedType("CommandParser", BindingFlags.NonPublic);
            if (cmdParser == null)
                throw new ApplicationException("The nested class CommandParser is not found.");

            proxyobjectType = cmdParser.GetNestedType("TinyCharBuffer", BindingFlags.NonPublic);
            if (proxyobjectType == null)
                throw new ApplicationException("The nested class TinyCharBuffer is not found.");

            proxyObject = Activator.CreateInstance(proxyobjectType, capacity);

            if (proxyObject == null)
                throw new ApplicationException("TinyCharBuffer object can't be created.");
        }

        public void Append(char ch) {
            MethodInfo method = proxyobjectType.GetMethod("Append");
            if (method == null)
                throw new ApplicationException("The TinyCharBuffer don't have Append mehotd.");

            try {
                method.Invoke(proxyObject, new object[] { ch });
            } catch (TargetInvocationException tte) {
                throw tte.InnerException;
            }
        }

        public char Pop() {
            MethodInfo method = proxyobjectType.GetMethod("Pop");
            if (method == null)
                throw new ApplicationException("The TinyCharBuffer don't have Pop mehotd.");

            try {
                object obj = method.Invoke(proxyObject, null);
                return (char)obj;
            } catch (TargetInvocationException tte) {
                throw tte.InnerException;
            }
        }

        public new string ToString() {
            MethodInfo method = proxyobjectType.GetMethod("ToString");

            try {
                object obj = method.Invoke(proxyObject, null);
                return (string)obj;
            } catch (TargetInvocationException tte) {
                throw tte.InnerException;
            }
        }
    }
}
